const str: string = 'hello';
const array: string[] = ['hello'];
const readonlyArray: readonly string[] = ['hello'];

str.includes('h');
array.includes('h');
readonlyArray.includes('h');

const str: string;
const array: any[];
const readonlyArray: ReadonlyArray<any>;
const typedArray: UInt8Array;
const maybe: string;
const userDefined: {
  indexOf(x: any): number;
  includes(x: any): boolean;
};

str.includes(value);
array.includes(value);
!readonlyArray.includes(value);
typedArray.includes(value);
maybe?.includes('');
userDefined.includes(value);

str.includes('example');

// The two methods have different parameters.
declare const mismatchExample: {
  indexOf(x: unknown, fromIndex?: number): number;
  includes(x: unknown): boolean;
};


function f(a: string): void {
  a.indexOf(b);
}

function f1(a: string): void {
  a.indexOf(b) + 0;
}

function f2(a: string | { value: string }): void {
  a.indexOf(b) !== -1;
}

type UserDefined = {
  indexOf(x: any): number; // don't have 'includes'
};
function f3(a: UserDefined): void {
  a.indexOf(b) !== -1;
}

type UserDefined = {
  indexOf(x: any, fromIndex?: number): number;
  includes(x: any): boolean; // different parameters
};
function f(a: UserDefined): void {
  a.indexOf(b) !== -1;
}

type UserDefined = {
  indexOf(x: any, fromIndex?: number): number;
  includes(x: any, fromIndex: number): boolean; // different parameters
};
function f(a: UserDefined): void {
  a.indexOf(b) !== -1;
}

type UserDefined = {
  indexOf(x: any, fromIndex?: number): number;
  includes: boolean; // different type
};
function f4(a: UserDefined): void {
  a.indexOf(b) !== -1;
}

function f5(a: string): void {
  /bar/i.test(a);
}

function f6(a: string): void {
  /ba[rz]/.test(a);
}

function f7(a: string): void {
  /foo|bar/.test(a);
}

function f8(a: string): void {
  /bar/.test();
}

function f9(a: string): void {
  something.test(a);
}

const pattern = new RegExp('bar');
function f11(a) {
  return pattern.test(a);
}